﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace OsuKeyboard
{
    public partial class ColorTable : Form
    {
        public ColorTable()
        {
            InitializeComponent();
        }
        // 窗口加载事件
        private void ColorTable_Load(object sender, EventArgs e)
        {
            CheckLanguage();
            colorEditorManager1.Color = Color.White;
            GetColorList();
            AddMouseUpEvent();
        }
        // 键盘按下事件（用于快捷键设置颜色表）
        private void ColorTable_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Back)     //删除颜色值 光标上移
            {
                colorListBox1.RemoveSelectedColor(false);
            }
            if (e.KeyCode == Keys.Delete)   //删除颜色值 光标下移
            {
                colorListBox1.RemoveSelectedColor(true);
            }
            if (e.KeyCode == Keys.Insert)   //插入颜色值
            {
                colorListBox1.InsertIndexColor(colorEditorManager1.Color);
            }
            if (e.KeyCode == Keys.Add)      //添加颜色值
            {
                colorListBox1.AddLastColor(colorEditorManager1.Color);
            }

        }
        // 界面语言设置
        private void CheckLanguage()
        {
            FormMain mainForm = (FormMain)this.Owner;

            this.Text = Languages.GetLang("ColorTable") + "-" + mainForm.SelectedLB.Text;
            Change.Text = Languages.GetLang(Change.Name);
            Clear.Text = Languages.GetLang(Clear.Name);
            Remove.Text = Languages.GetLang(Remove.Name);
            Insert.Text = Languages.GetLang(Insert.Name);
            Add.Text = Languages.GetLang(Add.Name);
            Accept.Text = Languages.GetLang(Accept.Name);
            Cancel.Text = Languages.GetLang(Cancel.Name);
        }
        // 颜色表获取
        private void GetColorList()
        {
            colorListBox1.Items.Clear();
            string LedName = ((FormMain)this.Owner).SelectedLB.Name;
            if (LedName == "LColor")
			{
				colorListBox1.Items.AddRange(DevCfg.LED1_ColorTable.Cast<object>().ToArray());
            }
            if (LedName == "RColor")
			{
				colorListBox1.Items.AddRange(DevCfg.LED2_ColorTable.Cast<object>().ToArray());
			}
            if (LedName == "MColor")
			{
				colorListBox1.Items.AddRange(DevCfg.LED3_ColorTable.Cast<object>().ToArray());
			}
            colorListBox1.SelectedIndex = 0;
        }

        // 颜色表选择项变更事件
        private void ColorListBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            colorListLength.Text = (colorListBox1.SelectedIndex + 1) + " / " + colorListBox1.Items.Count;
            if (colorListBox1.SelectedItem == null)
            {
                colorListLength.BackColor = Color.Transparent;
            }
            else
            {
                colorListLength.BackColor = (Color)colorListBox1.SelectedItem;
            }
        }

        // 颜色表长度指示器字体颜色自适应
        private void ColorListLength_BackColorChanged(object sender, EventArgs e)
        {
            Label colorLength = sender as Label;
            Color Bcolor = colorLength.BackColor;
            Boolean ColorGam = Bcolor.GetBrightness() > 0.4 && (Bcolor.R + Bcolor.G > 100);
            colorLength.ForeColor = ColorGam ? Color.Black : Color.White;
        }

        // 调色盘颜色变更事件
        private void ColorEditorManager1_ColorChanged(object sender, EventArgs e)
        {
            Color selectColor = colorEditorManager1.Color;
            PickerPanel.BackColor = Color.FromArgb(selectColor.R, selectColor.G, selectColor.B);
        }
        
        // 添加鼠标弹起事件
        private void AddMouseUpEvent()
        {
            foreach (Button ClickBT in ButtonPanel.Controls)
            {
                ClickBT.MouseUp += new MouseEventHandler(ButtonPanel_MouseUp);
            }
        }
        // 处理ButtonPanel鼠标弹起事件
        private void ButtonPanel_MouseUp(object sender, MouseEventArgs e)
        {
            Button ClickBT = sender as Button;
            colorWheel1.Focus();
            if (ClickBT.Name == "Change") { colorListBox1.ChangeSelectedColor(PickerPanel.BackColor); }
            if (ClickBT.Name == "Clear") { colorListBox1.Items.Clear(); }
            if (ClickBT.Name == "Remove") { colorListBox1.RemoveSelectedColor(true); }
            if (ClickBT.Name == "Insert") { colorListBox1.InsertIndexColor(PickerPanel.BackColor); }
            if (ClickBT.Name == "Add") { colorListBox1.AddLastColor(PickerPanel.BackColor); }
            if (ClickBT.Name == "Cancel") { this.Close(); }
            if (ClickBT.Name == "Accept")
            {
                if (colorListBox1.Items.Count < 1)
                {
                    MessageBox.Show("颜色表不能为空！\r\nThe color table can not be empty!");
                    return;
                }
                SetColorList();
                this.Close();
            }
        }
        // 颜色表设置
        private void SetColorList()
        {
            FormMain mainForm = (FormMain)this.Owner;
            string LedName = mainForm.SelectedLB.Name;

			List<byte[]> sendColorTable = new List<byte[]>();
			Color[] colorTable = colorListBox1.Items.Cast<Color>().ToArray();   // ObjectCollection -> List<Color> -> Color[]
			if (LedName == "LColor")
			{
				DevCfg.LED1_ColorTable = colorTable;
				for (uint AddrH = 1; AddrH <= 3; AddrH++)
				{
					for (uint AddrL = 0; AddrL < 16; AddrL++)
					{
						sendColorTable.Add(DevCfg.FlashCode[AddrH, AddrL]);
					}
				}
			}
            if (LedName == "RColor")
			{
				DevCfg.LED2_ColorTable = colorTable;
				for (uint AddrH = 4; AddrH <= 6; AddrH++)
				{
					for (uint AddrL = 0; AddrL < 16; AddrL++)
					{
						sendColorTable.Add(DevCfg.FlashCode[AddrH, AddrL]);
					}
				}
			}
			if (LedName == "MColor")
			{
				DevCfg.LED3_ColorTable = colorTable;
				for (uint AddrH = 7; AddrH <= 9; AddrH++)
				{
					for (uint AddrL = 0; AddrL < 16; AddrL++)
					{
						sendColorTable.Add(DevCfg.FlashCode[AddrH, AddrL]);
					}
				}
			}

			mainForm.AddDataBuffer(sendColorTable);
        }
	}

	/// <summary>
	/// 重写ListBox为ColorListBox
	/// </summary>
	class ColorListBox : ListBox
    {
		/// <summary>
		/// 初始化控件
		/// </summary>
		public ColorListBox()
        {
            this.DrawMode = DrawMode.OwnerDrawFixed;
			Array allColors = Enum.GetValues(typeof(KnownColor));//获取系统颜色名存入列表    
            foreach (KnownColor var in allColors)
            {
                this.Items.Add(Color.FromKnownColor(var));
            }
		}

        // 重写控件绘制事件
        protected override void OnDrawItem(DrawItemEventArgs e)
        {
            if (e.Index < 0) return;
            e.DrawBackground();                                 //绘制背景色
            Color IndexColor = (Color)this.Items[e.Index];      //获取颜色值
            SolidBrush brush = new SolidBrush(IndexColor);      //定义画刷
            Rectangle rect = e.Bounds;                          //获取Item的边界大小
            int boxLine = 20;                                   //定义颜色块长度
            Rectangle rectColor = new Rectangle(rect.Location, new Size(boxLine, rect.Height)); //创建绘图区域
            e.Graphics.FillRectangle(brush, rectColor);         //填充颜色(绘制色块) 
            Font font = new Font("宋体", 10);                   //定义字体        
            e.Graphics.DrawString(ColorToHex(IndexColor), font, Brushes.Black, (rect.X + boxLine + 2), rect.Y);//绘制文字    
            e.DrawFocusRectangle();                             //绘制焦点框
        }

        /// <summary>
        /// 转换Color为16进制编码
        /// </summary>
        /// <param name="color">Color颜色结构</param>
        /// <returns></returns>
        public string ColorToHex(Color color)
        {
            return "#" + color.R.ToString("X2") + color.G.ToString("X2") + color.B.ToString("X2");
        }
        /// <summary>
        /// 修改选定项
        /// </summary>
        public void ChangeSelectedColor(Color color)
        {
            this.Items[this.SelectedIndex] = color;
        }
        /// <summary>
        /// 删除选定项(selector=true光标下移，否则上移)
        /// </summary>
        public void RemoveSelectedColor(bool selector)
        {
            int selectIndex = this.SelectedIndex;
            if (selectIndex < 0) return;
            while (this.SelectedIndices.Count > 0)
            {
                this.Items.RemoveAt(this.SelectedIndex);
            }
            this.ClearSelected();
            if (this.Items.Count > selectIndex)
            {
                if (selector) this.SelectedIndex = selectIndex;
                else this.SelectedIndex = selectIndex - 1;
            }
            else
            {
                this.SelectedIndex = this.Items.Count - 1;
            }
        }
        /// <summary>
        /// 在指定索引处插入项
        /// </summary>
        /// <param name="color">Color颜色结构</param>
        public void InsertIndexColor(Color color)
        {
            if (this.Items.Count == 256)
            {
                MessageBox.Show("颜色数已达到上限！\r\nThe number of colors has reached the upper limit!");
                return;
            }
            if (this.SelectedIndex < 0)
            {
                this.Items.Insert(0, color);
                this.SelectedIndex = 0;
            }
            else
            {
                int selectItem = this.SelectedIndex;
                this.Items.Insert(selectItem, color);
                this.ClearSelected();
                this.SelectedIndex = selectItem;
            }
        }
        /// <summary>
        /// 在列表结尾添加项
        /// </summary>
        /// <param name="color"></param>
        public void AddLastColor(Color color)
        {
            if (this.Items.Count == 256)
            {
                MessageBox.Show("颜色数已达到上限！\r\nThe number of colors has reached the upper limit!");
                return;
            }
            this.Items.Add(color);
            this.ClearSelected();
            this.SelectedIndex = this.Items.Count - 1;
        }

        #region 自定义属性  
        // 选择的颜色
        public Color SelectColor
        {
            get
            {
                if (this.SelectedIndex < 0) return Color.Black;
                return (Color)this.Items[this.SelectedIndex];
            }
        }
        #endregion
    }
}
